Fix `cargo doc`
authorAlex Crichton <alex@alexcrichton.com>
Sun, 22 Mar 2015 19:25:54 +0000 (12:25 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Sun, 22 Mar 2015 19:25:54 +0000 (12:25 -0700)
Both tweak how deep documentation is compiled as well as fixing up the
dependencies for a documented target.

src/bin/doc.rs
src/cargo/ops/cargo_compile.rs
src/cargo/ops/cargo_doc.rs
src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/mod.rs

index 65314fef2f76d917263aa0b752dca618ca2d50d8..6524ff52dbcb0180d3575fc6d6e1f5368d9590db 100644 (file)
@@ -46,7 +46,6 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
     let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
 
     let mut doc_opts = ops::DocOptions {
-        all: !options.flag_no_deps,
         open_result: options.flag_open,
         compile_opts: ops::CompileOptions {
             config: config,
@@ -58,7 +57,9 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
             exec_engine: None,
             filter: ops::CompileFilter::Everything,
             release: false,
-            mode: ops::CompileMode::Build,
+            mode: ops::CompileMode::Doc {
+                deps: !options.flag_no_deps,
+            },
         },
     };
 
index d74fa59b87975e0291becdbaffbec3d70e57fff5..e2aec36b4b017eab062845d57ade77c187cfa530 100644 (file)
@@ -66,6 +66,7 @@ pub enum CompileMode {
     Test,
     Build,
     Bench,
+    Doc { deps: bool },
 }
 
 pub enum CompileFilter<'a> {
@@ -168,6 +169,9 @@ pub fn compile_pkg(package: &Package, options: &CompileOptions)
         let mut build_config = try!(scrape_build_config(config, jobs, target));
         build_config.exec_engine = exec_engine.clone();
         build_config.release = release;
+        if let CompileMode::Doc { deps } = mode {
+            build_config.doc_all = deps;
+        }
 
         try!(ops::compile_targets(&targets, to_build,
                                   &PackageSet::new(&packages),
@@ -213,6 +217,7 @@ fn generate_targets<'a>(pkg: &'a Package,
         CompileMode::Test => test,
         CompileMode::Bench => &profiles.bench,
         CompileMode::Build => build,
+        CompileMode::Doc { .. } => &profiles.doc,
     };
     return match *filter {
         CompileFilter::Everything => {
@@ -243,6 +248,10 @@ fn generate_targets<'a>(pkg: &'a Package,
                         t.is_bin() || t.is_lib()
                     }).map(|t| (t, profile)).collect())
                 }
+                CompileMode::Doc { .. } => {
+                    Ok(pkg.targets().iter().filter(|t| t.documented())
+                          .map(|t| (t, profile)).collect())
+                }
             }
         }
         CompileFilter::Only { lib, bins, examples, tests, benches } => {
index 8845990121e582dc5a77276461ff04ce40e93ad8..fdfe8e3f6845df912ec5856c6284af5ab70c788b 100644 (file)
@@ -10,7 +10,6 @@ use sources::PathSource;
 use util::{CargoResult, human};
 
 pub struct DocOptions<'a, 'b: 'a> {
-    pub all: bool,
     pub open_result: bool,
     pub compile_opts: ops::CompileOptions<'a, 'b>,
 }
index 22d9dc01c4c77f36608c84fe056e01460ba8ae69..70ccd88ffdf6a65d8649f1d30f3f717dcc9597f4 100644 (file)
@@ -34,7 +34,6 @@ pub struct Context<'a, 'b: 'a> {
     pub exec_engine: Arc<Box<ExecEngine>>,
     pub fingerprints: HashMap<(&'a PackageId, &'a Target, &'a Profile, Kind),
                               Fingerprint>,
-    pub initialized: HashSet<&'a PackageId>,
     pub compiled: HashSet<(&'a PackageId, &'a Target, &'a Profile)>,
     pub build_config: BuildConfig,
 
@@ -92,7 +91,6 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
             fingerprints: HashMap::new(),
             profiles: profiles,
             compiled: HashSet::new(),
-            initialized: HashSet::new(),
         })
     }
 
@@ -331,6 +329,9 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
     pub fn dep_targets(&self, pkg: &Package, target: &Target,
                        profile: &Profile)
                        -> Vec<(&'a Package, &'a Target, &'a Profile)> {
+        if profile.doc {
+            return self.doc_deps(pkg);
+        }
         let deps = match self.resolve.deps(pkg.package_id()) {
             None => return Vec::new(),
             Some(deps) => deps,
@@ -384,6 +385,40 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
         return ret
     }
 
+    /// Returns the dependencies necessary to document a package
+    fn doc_deps(&self, pkg: &Package)
+                -> Vec<(&'a Package, &'a Target, &'a Profile)> {
+        let deps = self.resolve.deps(pkg.package_id()).into_iter();
+        let deps = deps.flat_map(|a| a).map(|id| {
+            self.get_package(id)
+        }).filter(|dep| {
+            pkg.dependencies().iter().find(|d| {
+                d.name() == dep.name()
+            }).unwrap().is_transitive()
+        }).filter_map(|dep| {
+            dep.targets().iter().find(|t| t.is_lib()).map(|t| (dep, t))
+        });
+
+        // To document a library, we depend on dependencies actually being
+        // built. If we're documenting *all* libraries, then we also depend on
+        // the documentation of the library being built.
+        let mut ret = Vec::new();
+        for (dep, lib) in deps {
+            ret.push((dep, lib, self.lib_profile(dep.package_id())));
+            if self.build_config.doc_all {
+                ret.push((dep, lib, &self.profiles.doc));
+            }
+        }
+
+        // Be sure to build/run the build script for documented libraries as
+        // well
+        let pkg = self.get_package(pkg.package_id());
+        if let Some(t) = pkg.targets().iter().find(|t| t.is_custom_build()) {
+            ret.push((pkg, t, self.build_script_profile(pkg.package_id())));
+        }
+        return ret
+    }
+
     /// Gets a package for the given package id.
     pub fn get_package(&self, id: &PackageId) -> &'a Package {
         self.package_set.iter()
index aba4c62627ca9cc3955e5723257ba475fad36a2f..d2ccaeb81ca4dc98decc8846271470e89dad0a7c 100644 (file)
@@ -42,6 +42,7 @@ pub struct BuildConfig {
     pub requested_target: Option<String>,
     pub exec_engine: Option<Arc<Box<ExecEngine>>>,
     pub release: bool,
+    pub doc_all: bool,
 }
 
 #[derive(Clone, Default)]